/*
 *  Copyright (C) 2010 Glauco
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package org.balisunrise.common.abstracts;

import java.util.ArrayList;
import java.util.List;
import org.balisunrise.common.FieldComponent;
import org.balisunrise.common.FieldInput;

/**
 *
 * @author Glauco
 */
public abstract class AbstractFieldLayout extends AbstractEntityField{


    protected List<FieldComponent> fields;
    protected Boolean jumpToNextRow;
    public static final String PROP_FIELDS = "fields";
    public static final String PROP_JUMPTONEXTROW = "jumpToNextRow";

    public AbstractFieldLayout() {
        fields = new ArrayList<FieldComponent>();
    }

    /**
     * Get the value of jumpToNextRow
     *
     * @return the value of jumpToNextRow
     */
    public Boolean getJumpToNextRow() {
        return jumpToNextRow;
    }

    /**
     * Set the value of jumpToNextRow
     *
     * @param jumpToNextRow new value of jumpToNextRow
     */
    public void setJumpToNextRow(Boolean jumpToNextRow) {
        Boolean oldJumpToNextRow = this.jumpToNextRow;
        this.jumpToNextRow = jumpToNextRow;
        changeSupport.firePropertyChange(PROP_JUMPTONEXTROW,
                oldJumpToNextRow, jumpToNextRow);
    }

    /**
     * Get the value of fields
     *
     * @return the value of fields
     */
    public List<FieldComponent> getFields() {
        return fields;
    }

    /**
     * Set the value of fields
     *
     * @param fields new value of fields
     */
    public void setFields(List<FieldComponent> fields) {
        List<FieldComponent> oldFields = this.fields;
        this.fields = fields;
        changeSupport.firePropertyChange(PROP_FIELDS, oldFields, fields);
    }

    /**
     * Adiciona um FieldComponent a este FieldLayout.
     * @param fieldComponent
     */
    public void addFieldComponent(FieldComponent fieldComponent){
        getFields().add(fieldComponent);
    }

    /**
     * Remove um FieldComponent deste FieldLayout.
     * @param fieldComponent à remover.
     * @return se o componente pertencia a este FieldLayout e foi removido.
     */
    public boolean removeFieldComponent(FieldComponent fieldComponent){
        return getFields().remove(fieldComponent);
    }

    /**
     * Retorna uma lista dos componetes (Objetos de
     * Representação Visual) para um Campo (Atributo) de uma entidade
     * (Classe).
     */
    public FieldComponent[] getFieldComponents(){
        
        if (fields == null || fields.isEmpty())
            return new FieldComponent[]{};

        return fields.toArray(new FieldComponent[fields.size()]);
    }

    /**
     * Retorna se as componentes devem ser visualizados em uma
     * nova linha do layout.
     */
    public boolean jumpToNextRow(){
        return getJumpToNextRow();
    }

    /**
     * Se o campo possui um componente que possa ser requerido o
     * focus, requere o focus para o componente e retorna
     * verdadeiro, caso contrario retorna falso.
     */
    public boolean requestFocus(){
        for (FieldComponent fc : fields) {
            if(fc.requestFocus())
                return true;
        }
        return false;
    }

    /**
     * Abilita ou desabilita a representação visual, caso exista.
     * Alguns componentes não podem ser abilitados e este método deve retornar
     * false neste casos.
     *
     * @param value se é para abilitar o componente ou desabilitar.
     * @return False se não é possível abilitar o componente, True caso
     * contrário.
     */
    public boolean setEnabled(boolean value){

        for (FieldComponent field : fields) {
            if(field instanceof FieldInput){
                FieldInput fi = (FieldInput) field;
                return fi.setEnabled(value);
            }
        }
        
        return false;
    }
}
